/**
 * 浮点型相加
 * @param {String} arg1 浮点型数
 * @param {String} arg2 浮点型数
 * @returns 
 */
function accAdd(arg1, arg2) {
	var r1, r2, m;
	try {r1 = arg1.toString().split(".")[1].length} catch (e) {r1 = 0}
	try {r2 = arg2.toString().split(".")[1].length} catch (e) {r2 = 0}
	m = Math.pow(10, Math.max(r1, r2))
	return (arg1 * m + arg2 * m) / m
}
//除法函数，用来得到精确的除法结果
//说明：javascript的除法结果会有误差，在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
//调用：div(arg1,arg2)
//返回值：arg1除以arg2的精确结果
function accDiv(arg1, arg2) {
  var t1 = 0,
    t2 = 0,
    r1,
    r2;
  try {
    t1 = arg1.toString().split(".")[1].length;
  } catch (e) {
    t1 = 0;
  }
  try {
    t2 = arg2.toString().split(".")[1].length;
  } catch (e) {
    t2 = 0;
  }
  r1 = Number(arg1.toString().replace(".", ""));
  r2 = Number(arg2.toString().replace(".", ""));
  return mul(r1 / r2, Math.pow(10, t2 - t1));
}



/**
 * 浮点型相减
 * @param {String} arg1 浮点型数
 * @param {String} arg2 浮点型数
 * @returns 
 */
function accSub(arg1, arg2)  {
    return accAdd(arg1, -arg2);
}

/**
 * 浮点型相乘
 * @param {String} arg1 浮点型数
 * @param {String} arg2 浮点型数
 * @returns 
 */
function accMul(arg1, arg2) {
	let m = 0,s1 = arg1.toString(),s2 = arg2.toString();
	try {m += s1.split(".")[1].length} catch (e) {}
	try {m += s2.split(".")[1].length} catch (e) {}
	return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
}

/**
 * 深拷贝
 * @param {Object} source
 * @returns
 */
function deepClone(source) {
    if (!source && typeof source !== 'object') {
        throw new Error('error arguments', 'deepClone')
    }
    const targetObj = source.constructor === Array ? [] : {}
    Object.keys(source).forEach(keys => {
        if (source[keys] && typeof source[keys] === 'object') {
            targetObj[keys] = deepClone(source[keys])
        } else {
            targetObj[keys] = source[keys]
        }
    })
    return targetObj
}

/**
 * 检验手机号是否正确
 * @param {String} mobile 手机号
 * @returns
 */
function validatemobile(mobile) {
	if (mobile.length == 0) {
		uni.showToast({ title: '请输入手机号码',icon:'none'})
		return false;
	}
	if (mobile.length != 11) {
		uni.showToast({ title: '请输入有效的手机号码',icon:'none'})
		return false;
	}
	var myreg = /^1[3-9]\d{9}$/
	if (!myreg.test(mobile)) {
		uni.showToast({ title: '请输入有效的手机号码',icon:'none'})
		return false;
	}
	return true;
}

/**
 * 检验是否不为空
 * @param {String}
 * @returns
 */
function validate(str,casue) {
	if (str.length == 0) {
		uni.showToast({ title:casue,icon:'none'})
		return false;
	}
	return true;
}

/**
 * 校验身份证是否正确
 * @param {String} Arg_ID 身份证号
 * @returns
 */
function ID_Validity(Arg_ID) {    
    num = Arg_ID.toUpperCase(); //身份证号码为15位或者18位，15位时全为数字，18位前17位为数字，最后一位是校验位，可能为数字或字符X。         
    if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(num))) {           
        return false;          
    }   
    //验证前2位，城市符合  
    var aCity={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"};  
    if(aCity[parseInt(num.substr(0,2))]==null){  
        return false;  
    }   
    //下面分别分析出生日期和校验位  
    var len, re; len = num.length;   
    if (len == 15) {  
        re = new RegExp(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/);  
        var arrSplit = num.match(re);  //检查生日日期是否正确  
        var dtmBirth = new Date('19' + arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4]);  
        var bGoodDay; bGoodDay = (dtmBirth.getYear() == Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3])) && (dtmBirth.getDate() == Number(arrSplit[4]));  
        if (!bGoodDay) {          
            return false;  
        } else { //将15位身份证转成18位 //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。         
            var arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);          
            var arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');       
            var nTemp = 0, i;             
            num = num.substr(0, 6) + '19' + num.substr(6, num.length - 6);            
            for(i = 0; i < 17; i ++) {                  
                nTemp += num.substr(i, 1) * arrInt[i];         
            }  
            num += arrCh[nTemp % 11];  
            return true;  
        }  
    }  
    if (len == 18) {  
        re = new RegExp(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/);  
        var arrSplit = num.match(re);  //检查生日日期是否正确  
        var dtmBirth = new Date(arrSplit[2] + "/" + arrSplit[3] + "/" + arrSplit[4]);  
        var bGoodDay; bGoodDay = (dtmBirth.getFullYear() == Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3])) && (dtmBirth.getDate() == Number(arrSplit[4]));  
        if (!bGoodDay) {  
            return false;  
        }  
        else { //检验18位身份证的校验码是否正确。 //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。  
            var valnum;  
            var arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);  
            var arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');  
            var nTemp = 0, i;  
            for(i = 0; i < 17; i ++) {  
                nTemp += num.substr(i, 1) * arrInt[i];  
            }  
            valnum = arrCh[nTemp % 11];  
            if (valnum != num.substr(17, 1)) {  
                return false;  
            }  
            return true;  
        }  
    } return false;  
}

/**
 * 提取身份证号中生日
 * @param {String} Arg_ID 身份证号
 * @returns
 */
function Return_BirthdayByID(Arg_ID) {
	//获取出生日期
	var ls_Birthday = Arg_ID.substring(6, 10) + "-" + Arg_ID.substring(10, 12) + "-" + Arg_ID.substring(12, 14);
	return ls_Birthday;
}

/**
 * 提取身份证中年龄
 * @param {String} Arg_ID 身份证号
 * @returns
 */
function Return_AgeByID(Arg_ID) {
	//获取年龄
	var myDate = new Date();
	var month = myDate.getMonth() + 1;
	var day = myDate.getDate();
	var age = myDate.getFullYear() - Arg_ID.substring(6, 10) - 1;
	if (Arg_ID.substring(10, 12) < month || Arg_ID.substring(10, 12) == month && Arg_ID.substring(12, 14) <= day) {
		age++;
	}
	return age;
}

/**
 * 提取身份证中性别
 * @param {String} Arg_ID 身份证号
 * @returns
 */
function Return_SexByID(Arg_ID){
	//获取性别
	if (parseInt(Arg_ID.substr(16, 1)) % 2 == 1) {
		//男
		return "男";
	} else {
		//女
		return "女";
	}
}

/**
 * 将数字转换成汉字
 * @param {Object} num 整形
 * @returns
 */
function toChinesNum(num) {
    let changeNum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; //changeNum[0] = "零"
    let unit = ["", "十", "百", "千", "万"];
    num = parseInt(num);
    let getWan = (temp) => {
        let strArr = temp.toString().split("").reverse();
        let newNum = "";
        for (var i = 0; i < strArr.length; i++) {
            newNum = (i == 0 && strArr[i] == 0 ? "" : (i > 0 && strArr[i] == 0 && strArr[i - 1] == 0 ? "" : changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i]))) + newNum;
        }
        return newNum;
    }
    let overWan = Math.floor(num / 10000);
    let noWan = num % 10000;
    if (noWan.toString().length < 4) noWan = "0" + noWan;
    return overWan ? getWan(overWan) + "万" + getWan(noWan) : getWan(num);

}

/**
 * 小程序专用，调出地图选择坐标
 * @returns
 */
function chooseLocation(callback){
	// 调出地图
	uni.chooseLocation({
		success: (res) => {//成功
			callback(res)
		},
		fail:()=>{//失败
			//获取用户的当前设置。
			uni.getSetting({success: (res) => {
				if (!res.authSetting['scope.userLocation']) {
					uni.showModal({title: "是否授权当前位置",content: "需要获取您的地理位置，请确认授权，否则地图功能将无法使用",
						success: (tip) => {
							if (tip.confirm) {
								// 如果用户同意授权地理信息，则打开授权设置页面，判断用户的操作
								uni.openSetting({
									success: (data) => {
										// 如果用户授权了地理信息在，则提示授权成功
										if (data.authSetting['scope.userLocation'] === true) {
											uni.showToast({title: "授权成功",icon: "success"})
											// 授权成功后，然后再次chooseLocation获取信息
											uni.chooseLocation({success: (res) => {callback(res)}})
										} else {
											uni.showToast({title: "授权失败",icon: "none"})
										}
									}
								})
							}
						},
					})
				}},
				fail: (res) => {
					uni.showToast({
						title: "调用授权窗口失败",
						icon: "none",
					})
				}
			})
		}
	})
}

module.exports = {
	accAdd,
	accSub,
	accMul,
	deepClone,
	validatemobile,
	validate,
	ID_Validity,
	Return_BirthdayByID,
	toChinesNum,
	chooseLocation
}